package com.xnyzc.lhy.didi.service.impl.tongcheng;

import com.alibaba.fastjson.JSON;
import com.xnyzc.lhy.common.component.redis.RedisCommon;
import com.xnyzc.lhy.common.constant.RedisPrefixConstant;
import com.xnyzc.lhy.common.entity.Qw;
import com.xnyzc.lhy.common.entity.Rv;
import com.xnyzc.lhy.common.penum.EErrorCode;
import com.xnyzc.lhy.common.penum.order.EOrderStatus;
import com.xnyzc.lhy.common.util.CheckUtil;
import com.xnyzc.lhy.common.util.MD5Util;
import com.xnyzc.lhy.common.util.http.HttpRequestUtil;
import com.xnyzc.lhy.didi.entity.order.OaCOrderPersonal;
import com.xnyzc.lhy.didi.entity.param.synchronization.StatusCallbackParam;
import com.xnyzc.lhy.didi.mapper.order.OaCOrderPersonalMapper;
import com.xnyzc.lhy.didi.mapper.other.OaDUserInfoMapper;
import com.xnyzc.lhy.didi.mapper.sys.OaSysOfficeMapper;
import com.xnyzc.lhy.didi.service.tongcheng.TcOrderStatusSyncService;
import com.xnyzc.lhy.didi.tongcheng.entity.results.TcResponse;
import com.xnyzc.lhy.didi.tongcheng.penum.ETongChengErrorCode;
import com.xnyzc.lhy.order.entity.gps.OaDVehicleGps;
import com.xnyzc.lhy.order.entity.sidebar.OaSysOffice;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

@Slf4j
@Service
public class TcOrderStatusSyncServiceImpl implements TcOrderStatusSyncService {

    //供应商编码
    @Value("${global.tc.supplyCode}")
    private String supplyCode;

    //同程分配
    @Value("${global.tc.clientId}")
    private String clientId;

    //同程密钥
    @Value("${global.tc.token}")
    private String token;

    //回调地址
    @Value("${global.tc.callback}")
    private String callback;

    @Autowired
    private OaCOrderPersonalMapper oaCOrderPersonalMapper;

    @Autowired
    private OaDUserInfoMapper oaDUserInfoMapper;

    @Autowired
    private OaSysOfficeMapper oaSysOfficeMapper;

    @Autowired
    private RedisCommon redisCommon;

    @Override
    public Rv handle(StatusCallbackParam statusCallbackParam) {
        Map<String, Object> params = new HashMap<>();
        String orderId = statusCallbackParam.getOrder_id();
        if (CheckUtil.strIsEmpty(orderId)) {
            return Rv.error(EErrorCode.unOrder);
        }
        OaCOrderPersonal personal = oaCOrderPersonalMapper.selectOne(Qw.create().eq(OaCOrderPersonal.ORDER_NO, orderId));
        if (personal == null) {
            return Rv.error(EErrorCode.unOrder);
        }
        String personalId = personal.getPersonalId().toString();
        EOrderStatus status = EOrderStatus.findById(statusCallbackParam.getStatus());
        if(null == status){//确保拿到正确的状态
            return Rv.error(EErrorCode.unWalletRecordType);
        }
        switch (status) {
            case reassigned:
            case orderTimeout: {
                params.put("orderId", personalId);
                params.put("cancelReason", statusCallbackParam.getExtra());
//                String res = sendToTC("9", params);
                return sendToTC(9, params);
            }
            case driverOrder: {
                String driverId = statusCallbackParam.getDriver_id();
                if (CheckUtil.strIsEmpty(driverId)) {
                    return Rv.error(EErrorCode.unOrder);
                }
                /*if (!driverId.equals(personal.getDriverId().toString())) {
                    return Rv.error(EErrorCode.unOrder);
                }*/
                Map<String, Object> driverInfo = oaDUserInfoMapper.getDriverInfo(driverId);
                if (driverInfo.get("driverId") == null) {
                    return Rv.error(EErrorCode.unOrder);
                }
                Integer serviceScore = (Integer) driverInfo.get("serviceScore");
                double star = Math.ceil(serviceScore / 20.0);
                BigDecimal mlat = statusCallbackParam.getDriver_lat();
                BigDecimal mlng = statusCallbackParam.getDriver_lng();
                String lat = "30.622635";
                String lng = "104.039334";
                if (mlat != null) {
                    lat = String.format("%.6f", mlat.doubleValue());
                }
                if (mlng != null) {
                    lng = String.format("%.6f", mlng.doubleValue());
                }

                params.put("driverName", driverInfo.get("driverName"));//司机姓名
                params.put("driverTel", driverInfo.get("driverPhone"));//司机电话
                params.put("carNo", driverInfo.get("vehNo"));//车牌号
                params.put("carType", driverInfo.get("vehType"));//车辆名称
                params.put("carColor", driverInfo.get("vehColor"));//车辆颜色
                params.put("orderId", personalId);//供应商订单号
                params.put("tcOrderNo", personal.getOrderNo());//同程订单号
                params.put("driverPhoneReal", driverInfo.get("driverPhone"));//司机真实手机号
                params.put("driverLevel", String.format("%.1f", star));//司机星级（如：4.5   5.0）
                params.put("driverLat", lat);//司机纬度
                params.put("driverLng", lng);//司机经度
                // params.put("hasVirtual", 0);//司机接单传0
//                String res = sendToTC("3", params);
                //因为一开始有默认司机接单，故所有司机的接单均为改单
                return sendToTC(11, params);
            }
            case changeDriver: {
                String driverId = statusCallbackParam.getDriver_id();
                if (CheckUtil.strIsEmpty(driverId)) {
                    return Rv.error(EErrorCode.unOrder);
                }
                if (!driverId.equals(personal.getDriverId())) {
                    return Rv.error(EErrorCode.unOrder);
                }
                Map<String, Object> driverInfo = oaDUserInfoMapper.getDriverInfo(driverId);
                if (driverInfo.get("driverId") == null) {
                    return Rv.error(EErrorCode.unOrder);
                }
                Integer serviceScore = (Integer) driverInfo.get("serviceScore");
                double star = Math.ceil(serviceScore / 20.0);
                BigDecimal mlat = statusCallbackParam.getDriver_lat();
                BigDecimal mlng = statusCallbackParam.getDriver_lng();
                String lat = "30.622635";
                String lng = "104.039334";
                if (mlat != null) {
                    lat = String.format("%.6f", mlat.doubleValue());
                }
                if (mlng != null) {
                    lng = String.format("%.6f", mlng.doubleValue());
                }

                params.put("driverName", driverInfo.get("driverName"));//司机姓名
                params.put("driverTel", driverInfo.get("driverPhone"));//司机电话
                params.put("carNo", driverInfo.get("vehNo"));//车牌号
                params.put("carType", driverInfo.get("vehType"));//车辆名称
                params.put("carColor", driverInfo.get("vehColor"));//车辆颜色
                params.put("orderId", personalId);//供应商订单号
                params.put("tcOrderNo", personal.getOrderNo());//同程订单号
                params.put("driverPhoneReal", driverInfo.get("driverPhone"));//司机真实手机号
                params.put("driverLevel", String.format("%.1f", star));//司机星级（如：4.5   5.0）
                params.put("driverLat", lat);//司机纬度
                params.put("driverLng", lng);//司机经度
                //params.put("hasVirtual", 0);//司机接单传0
//                String res = sendToTC("11", params);sz
                return sendToTC(11, params);
            }
            case reservationLocation: {
                params.put("orderId", personalId);
//                String res = sendToTC("12", params);
                return sendToTC(12, params);
            }
            case driverArrived: {
                params.put("orderId", personalId);
//                String res = sendToTC("5", params);
                return sendToTC(5, params);
            }
            case duringTrip: {
                params.put("orderId", personalId);
//                String res = sendToTC("6", params);
                return sendToTC(6, params);
            }
            case sendBill: {
                params.put("orderId", personalId);
                params.put("settleAmt", statusCallbackParam.getExtra());
//                String res = sendToTC("7", params);//回调结算金额（单位：元）
                return sendToTC(7, params);//回调结算金额（单位：元）
            }
            case normalOrderPendingPayment: {
                params.put("orderId", personalId);
                params.put("settleAmt", statusCallbackParam.getExtra());
//                String res = sendToTC("8", params);//回调结算金额（单位：元）
                return sendToTC(8, params);//回调结算金额（单位：元）
            }
            default: {
                return Rv.error(EErrorCode.applyAmountOperateFailure);
            }
        }
    }

    @Override
    public Rv bindDefaultDriver(OaCOrderPersonal personal) {
        return sendToTC(3, getDefaultDriver(personal));
    }

    /**
     * @param status 同程状态码-2供应商接单；3司机接单；4接单失败（无司机或者取消）；5司机到达；6.行程中；7行程结束；8供应商结算；9订单取消（客服取消）；11司机改派；12司机已出发
     * @param params
     * @return
     */
    private Rv sendToTC(int status, Map<String, Object> params) {
        params.put("tcOrderStatus", status);
        params.put("supplierCode", supplyCode);//供应商编号
        params.put("clientId", clientId);//同程分配
        //对参数名进行自然排序
        Set<Map.Entry<String, Object>> set = params.entrySet();
        List<Map.Entry<String, Object>> infoIds = new ArrayList<>(set);
        Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() {

            @Override
            public int compare(Map.Entry<String, Object> obj1, Map.Entry<String, Object> obj2) {
                return obj1.getKey().compareTo(obj2.getKey());
            }
        });
        // 构造URL键值对
        try {
            StringBuilder buffer = new StringBuilder();
            for (Map.Entry<String, Object> item : infoIds) {
                if (CheckUtil.strIsNotEmpty(item.getKey())) {
                    String key = item.getKey();
                    Object val = item.getValue();
                    if (val != null) {
                        buffer.append(key + "=" + val.toString());
                        buffer.append("&");
                    }
                }
            }
            String string = buffer.toString();
            String mstri1 = string + "token=" + token;
            log.info("Token-" + mstri1);
            String sign = MD5Util.MD5(mstri1).toLowerCase();
            params.put("sign", sign);
            String jsonString = JSON.toJSONString(params);
            log.info("TcSync-" + jsonString);
            String result = HttpRequestUtil.requestPostJson(callback, jsonString);
            log.info("TcSync-" + result);
            TcResponse response = JSON.parseObject(result, TcResponse.class);
            if (response != null && response.getCode() == ETongChengErrorCode.success.getValue()) {
                return Rv.wrap();
            }
            return Rv.error(EErrorCode.gatewayDeny);
        } catch (IOException e) {
            log.error("sendToTC-消息同步失败：",e);
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取一个默认接单账户-用于保证接单率
     *
     * @param personal
     * @return
     */
    private Map<String, Object> getDefaultDriver(OaCOrderPersonal personal) {
        Long officeId = personal.getOfficeId();
        Integer verType = personal.getVehicleType();
        OaSysOffice company = oaSysOfficeMapper.selectOne(Qw.create().eq(OaSysOffice.OFFICE_ID, personal.getOfficeId()));
        Map<String, Object> driverInfo = oaSysOfficeMapper.getCompanyDriver(officeId, verType);
        Object driverId = driverInfo.get("driverId");
        if (driverId == null) {
            log.info("Without driver -" + officeId + ":" + verType);
            return null;
        }
        String lat = "30.622635";
        String lng = "104.039334";
        String str = redisCommon.getStr(RedisPrefixConstant.GPS_VEH_KEY_PREFIX + driverId);
        if (CheckUtil.strIsNotEmpty(str)) {
            OaDVehicleGps oaDVehicleGps = JSON.parseObject(str, OaDVehicleGps.class);
            lng = oaDVehicleGps.getLng();
            lat = oaDVehicleGps.getLat();
        }
        Object vehColor = driverInfo.get("vehColor");
        String mvehColor = "无颜色";
        if (vehColor != null) {
            mvehColor = vehColor.toString();
        }

        /*Integer serviceScore = (Integer) driverInfo.get("serviceScore");
        double star = Math.ceil(serviceScore / 20.0);*/
        Map<String, Object> params = new HashMap<>();
        params.put("driverName", company.getPrimaryPerson());//司机姓名-这里是公司管理员名字
        params.put("driverTel", company.getPhone());//司机电话
        params.put("carNo", driverInfo.get("vehNo"));//车牌号
        params.put("carType", driverInfo.get("vehType"));//车辆名称
        params.put("carColor", mvehColor);//车辆颜色
        params.put("orderId", personal.getPersonalId());//供应商订单号
        params.put("tcOrderNo", personal.getOrderNo());//同程订单号
        params.put("driverPhoneReal", company.getPhone());//司机真实手机号
        params.put("driverLevel", "5.0");//司机星级（如：4.5   5.0）
        params.put("driverLat", lat);//司机纬度
        params.put("driverLng", lng);//司机经度
        params.put("hasVirtual", 1);//车头接单传1 表示虚拟接单（1是  0否）
        return params;
    }
}
